package com.ruoyi.business.youdaoController.shangyou;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Splitter;
import com.google.common.collect.Maps;
import com.ruoyi.business.services.HttpService;
import com.ruoyi.business.utils.MapStrUtil;
import com.ruoyi.business.utils.Md5Util;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.SaveType;
import com.ruoyi.common.utils.EncrypDES;
import com.ruoyi.common.utils.GetUrlParam;
import com.ruoyi.common.utils.OtherUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.domain.vo.R;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * 优酷->小红书
 */
@RestController
@RequestMapping("ownYkToXHSApi")
public class YKToXHSController {

    @Autowired
    private RedisCache redisCache;
    @Autowired
    private HttpService httpService;

    private final static String CLASSESEN = "youdao";


    /**
     * http://www.ssptqt.com:9185/ownYkToXHSApi/send?channelId=&dmpid=__TRACKID__&idfa=__IDFA__&imei=__IMEI__&oaid=__OAID__&ip=__IP__&ua=__UA__&os=__OS__&androidId=__ANDROIDID__&mac=__MAC__&caid=__CAID__&ts_sec=__TIMESTAMP__&callback_url=__CALLBACKURL__
     * @param request
     * @return
     * @throws Exception
     */
    @Log(title = "有道", businessType = BusinessType.ESCALATION, esIndex = "youdao_log", saveType = SaveType.ES)
    @RequestMapping("/send")
    public Object send(HttpServletRequest request) throws Exception {
        String queryString = request.getQueryString();
        String channelId = request.getParameter("channelId");
        String dmpid = request.getParameter("dmpid");
        if(StringUtils.isBlank(channelId) || "null".equals(channelId)){
            return R.failure().msg("channelId不能为空");
        }
        if(StringUtils.isBlank(dmpid) || "null".equals(dmpid)){
            return R.failure().msg("dmpid不能为空");
        }

        Map<String, Object> baseParamsMap = GetUrlParam.queryStrToMap(queryString);

        baseParamsMap.remove("channelId");
        baseParamsMap.remove("dmpid");

        Map<String, Object> channelDetail = redisCache.getCacheMapValue(CLASSESEN+"Cache", channelId);
        if(channelDetail == null){
            return R.failure().msg("channelId不正确");
        }
        if("0".equals(channelDetail.get("isopen")+"")){
            return R.failure().msg("channelId未开启");
        }
        String url = channelDetail.get("request_address") + "";
        String requestType = channelDetail.get("request_type") + "";
        String requestAddress = GetUrlParam.getRequestAddress(url);
        String staticParameters = GetUrlParam.TruncateUrlPage(url);
        Map<String, Object> staticParamsMap = GetUrlParam.queryStrToMap(staticParameters);
        baseParamsMap.putAll(staticParamsMap);


        String ua = baseParamsMap.get("ua") + "";
        String ip = baseParamsMap.get("ip") + "";
        if(StringUtils.isNotBlank(ua) && !"null".equals(ua)){
            ua = URLDecoder.decode(ua, Constants.UTF8);
        }else{
        }
        if(StringUtils.isNotBlank(ip) && !"null".equals(ip)){
        }else{
        }


        String imei = getMapValue(baseParamsMap, "imei");
        String oaid = getMapValue(baseParamsMap, "oaid");
        String idfa = getMapValue(baseParamsMap, "idfa");
        String androidId = getMapValue(baseParamsMap, "androidId");
        String mac = getMapValue(baseParamsMap, "mac");
        String caid = getMapValue(baseParamsMap, "caid");
        String os = getMapValue(baseParamsMap, "os");
        String tsSec = getMapValue(baseParamsMap, "ts_sec");

        String imeiMd5 = "";
        if(StringUtils.isNotBlank(imei)){
            imeiMd5 = DigestUtils.md5DigestAsHex(imei.getBytes(Constants.UTF8));
            baseParamsMap.put("imei_md5", imeiMd5);
        }
        String oaidMd5 = "";
        if(StringUtils.isNotBlank(oaid)){
            oaidMd5 = DigestUtils.md5DigestAsHex(oaid.getBytes(Constants.UTF8));
            baseParamsMap.put("oaid_md5", oaidMd5);
        }
        String idfaMd5 = "";
        if(StringUtils.isNotBlank(idfa)){
            idfaMd5 = DigestUtils.md5DigestAsHex(idfa.getBytes(Constants.UTF8));
            baseParamsMap.put("idfa_md5", idfaMd5);
        }
        String androidIdMd5 = "";
        if(StringUtils.isNotBlank(androidId)){
            androidIdMd5 = DigestUtils.md5DigestAsHex(androidId.getBytes(Constants.UTF8));
            baseParamsMap.put("android_id_md5", androidIdMd5);
        }
        String macMd5 = "";
        if(StringUtils.isNotBlank(mac)){
            macMd5 = DigestUtils.md5DigestAsHex(mac.getBytes(Constants.UTF8));
            baseParamsMap.put("mac_md5", macMd5);
        }

        String ts = (System.currentTimeMillis()/1000) + "";
        baseParamsMap.put("ts", ts);
        baseParamsMap.put("ua", URLEncoder.encode(ua, Constants.UTF8));
        baseParamsMap.put("ip", ip);

        String callbackUrlDecode = baseParamsMap.get("callback_url") + "";
        String callbackUrl = URLDecoder.decode(callbackUrlDecode, Constants.UTF8);
        callbackUrl = callbackUrl.replace("__ANDROIDID__", androidId);
        callbackUrl = callbackUrl.replace("__APPKEY__", "__APPKEY__");
        callbackUrl = callbackUrl.replace("__CAID__", caid);
        callbackUrl = callbackUrl.replace("__CONVAMOUNT__", "");
        callbackUrl = callbackUrl.replace("__CONVCOUNT__", "1");
        callbackUrl = callbackUrl.replace("__CREATIVEID__", "");
        callbackUrl = callbackUrl.replace("__DEEPCONV__", "1");
        callbackUrl = callbackUrl.replace("__EVENTTIME__", "__EVENTTIME__");
        callbackUrl = callbackUrl.replace("__EVENTTYPE__", "__EVENTTYPE__");
        callbackUrl = callbackUrl.replace("__IDFA__", idfa);
        callbackUrl = callbackUrl.replace("__IMEI__", imei);
        callbackUrl = callbackUrl.replace("__IP__", ip);
        callbackUrl = callbackUrl.replace("__MAC__", mac);
        callbackUrl = callbackUrl.replace("__OAID__", oaid);
        callbackUrl = callbackUrl.replace("__OS__", os);
        callbackUrl = callbackUrl.replace("__TRACKID__", dmpid);




        String callbackUrlRequestAddress = GetUrlParam.getRequestAddress(callbackUrl);
        String callbackUrlStaticParameters = GetUrlParam.TruncateUrlPage(callbackUrl);
        EncrypDES encrypDES = new EncrypDES();
        String callbackBase = OtherUtils.getServerUrl(request) + "ownYkToXHSApi/callback/"+channelId+"/"+dmpid+"/";
        String encrypt_u = encrypDES.encrypt(callbackUrlRequestAddress);
        String nu = callbackBase + encrypt_u + "?"+callbackUrlStaticParameters;
        baseParamsMap.put("callback_url", URLEncoder.encode(URLEncoder.encode(nu, Constants.UTF8), Constants.UTF8));


        Map<String, Object> baseParamsMapTemp = new HashMap<>();
        baseParamsMapTemp.put("callback_url", getMapValue(baseParamsMap, "callback_url"));
        baseParamsMapTemp.put("idfa", idfa);
        baseParamsMapTemp.put("idfa_sum", getMapValue(baseParamsMap, "idfa_md5"));
        baseParamsMapTemp.put("imei_sum", getMapValue(baseParamsMap, "imei_sum"));
        baseParamsMapTemp.put("ip", ip);
        baseParamsMapTemp.put("mac", mac);
        baseParamsMapTemp.put("media_name", "youku");
        baseParamsMapTemp.put("oaid", oaid);
        baseParamsMapTemp.put("oaid_sum", getMapValue(baseParamsMap, "oaid_md5"));
        baseParamsMapTemp.put("ts_sec", tsSec);
        baseParamsMapTemp.put("ua", ua);
        if("0".equals(os)){
            baseParamsMapTemp.put("os", "IOS");
        }else if("1".equals(os)){
            baseParamsMapTemp.put("os", "ANDROID");
        }

        List<String> tempList = new ArrayList<>();
        for(String key: baseParamsMapTemp.keySet()){
            String value = baseParamsMapTemp.get(key) + "";
            tempList.add(key+"="+value);
        }
        String requestParameters = String.join("&", tempList);

        String uuid = IdUtils.fastSimpleUUID();
        String reqType = "click";
        if("POST".equals(requestType)){
            httpService.sendPost(requestAddress, requestParameters, ip, ua, uuid, reqType);
        }else{
            httpService.sendGet(requestAddress, requestParameters, ip, ua, uuid, reqType);
        }
        return R.success().msg(uuid);
    }




    private String getMapValue(Map<String, Object> map, String key){
        if(map == null){
            return "";
        }
        if(map.get(key) == null){
            return "";
        }
        String val = map.get(key) + "";
        if("null".equals(val) || (val.startsWith("__") && val.endsWith("__"))){
            return "";
        }
        return val;
    }


    @Log(title = "有道", businessType = BusinessType.CALLBACK, esIndex = "youdao_log", saveType = SaveType.ES)
    @RequestMapping("/callback/{channelId}/{dmpid}/{encryptedUrl}")
    public Object send(HttpServletRequest request, @PathVariable("channelId") String channelId, @PathVariable("encryptedUrl") String encryptedUrl) throws Exception {
        Map<String, Object> channelDetail = redisCache.getCacheMapValue(CLASSESEN+"Cache", channelId);
        String appKey = channelDetail.get("callback_clientid") + "";
        String token = channelDetail.get("callback_secretkey") + "";

        String queryString = request.getQueryString();
        EncrypDES encrypDES = new EncrypDES();
        String requestAddress = encrypDES.decrypt(encryptedUrl);

        //获取请求参数, 并替换属性
        queryString = queryString.replace("__EVENTTIME__", System.currentTimeMillis()+"");
        queryString = queryString.replace("__EVENTTYPE__", "active");
        queryString = queryString.replace("__APPKEY__", appKey);

        String content = MapStrUtil.toStr(getObjectParams(requestAddress + "?" + queryString));
        String sign = sign(appKey, token, content);
        sign = sign.toUpperCase();

        queryString = queryString + "&sign=" + sign;
        String uuid = IdUtils.fastSimpleUUID();
        String reqType = "callback";
        httpService.sendGet(requestAddress, queryString, null, null, uuid, reqType);
        return R.success().msg(uuid);
    }

    public static Map<String, Object> getObjectParams(String url) {
        URL netUrl = null;

        try {
            netUrl = new URL(url);
        } catch (MalformedURLException var8) {
            return null;
        }

        if (netUrl == null) {
            return null;
        } else {
            Map<String, Object> m = Maps.newHashMap();
            String q = netUrl.getQuery();
            if (StringUtils.isBlank(q)) {
                return null;
            } else {
                List<String> list = Splitter.on("&").splitToList(q);
                if (CollectionUtils.isEmpty(list)) {
                    return null;
                } else {
                    Iterator var5 = list.iterator();

                    while(var5.hasNext()) {
                        String pair = (String)var5.next();
                        if (pair.contains("=")) {
                            List<String> keyValue = Splitter.on("=").splitToList(pair);
                            if (CollectionUtils.isNotEmpty(keyValue)) {
                                m.put(keyValue.get(0), keyValue.get(1));
                            }
                        }
                    }

                    return m;
                }
            }
        }
    }


    // 签名
    public static String sign(String appKey, String appSecret, String content) {
        StringBuilder keyBuilder = new StringBuilder();
        keyBuilder.append(appKey).append(content);
        return Md5Util.MD5(encrypt(keyBuilder.toString(), appSecret, "HmacSHA256"));
    }

    // HmacSHA256加密算法获取加密串
    public static String encrypt(String key, String appSecret, String cryptoType) {
        try {
            SecretKeySpec signingKey = getSecretKey(appSecret, cryptoType);
            Mac mac = Mac.getInstance(cryptoType);
            mac.init(signingKey);
            byte[] rawHmac = mac.doFinal(key.getBytes());
            String hexBytes = byte2hex(rawHmac);
            return hexBytes;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static SecretKeySpec getSecretKey(String appSecret, String cryptoType) {
        try {
            byte[] keyBytes = appSecret.getBytes();
            SecretKeySpec secretKey = new SecretKeySpec(keyBytes, cryptoType);
            return secretKey;
        } catch (Exception var4) {
            return null;
        }
    }

    private static String byte2hex(final byte[] b) {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = (Integer.toHexString(b[n] & 0xFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs;
    }


}
